﻿using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Media;

using AALib.Input;

namespace AALib.Audio
{
    public class MusicManager : GameComponent
    {
        #region Fields

        float m_fMusicVolume = 0.1f;
        private Dictionary<string, SoundEffect> m_sounds = new Dictionary<string, SoundEffect>();

        private SoundEffectInstance[] m_playingSounds = new SoundEffectInstance[32];
        private SoundEffectInstance[] m_loopingSounds = new SoundEffectInstance[32];
        private SoundEffectInstance[] m_playList = new SoundEffectInstance[32];
        private SoundEffectInstance[] m_musicList = new SoundEffectInstance[32];

        int m_lastListSong = 32, m_listnr = 0, m_musicListSpot = 31;
        bool m_playListStart = false, m_random, m_musicListStart;
        List<string> m_musicListString = new List<string>();

        //float soundVolume = 0.5f;

        #endregion

        #region Properties
        #endregion

        #region Inits

        public MusicManager(Game p_game)
            : base(p_game)
        {
        }

        public override void Initialize()
        {
            IniFile configFile = new IniFile("textRef\\Values.ini");
            configFile.Parse();

            // fMusicVolume = float.Parse( configFile.GetValue("Music", "MusicVolume") );
            m_fMusicVolume = 0.5f;
        }

        #endregion

        #region Various Functions

        public void LoadSound(string p_soundName)
        {
            LoadSound(p_soundName, "Audio//Music//" + p_soundName);
        }

        public void LoadSound(string p_soundName, string p_soundPath)
        {
            if (m_sounds.ContainsKey(p_soundName))
            {
                throw new InvalidOperationException(string.Format("Sound '{0}' has already been loaded", p_soundName));
            }

            m_sounds.Add(p_soundName, Game.Content.Load<SoundEffect>(p_soundPath));
        }

        public override void Update(GameTime p_gameTime)
        {
            for (int i = 0; i < m_playingSounds.Length; ++i)
            {
                if (m_playingSounds[i] != null && m_playingSounds[i].State == SoundState.Stopped)
                {
                    m_playingSounds[i].Dispose();
                    m_playingSounds[i] = null;
                }
            }

            for (int i = 0; i < m_loopingSounds.Length; ++i)
            {
                if (m_loopingSounds[i] != null && m_loopingSounds[i].State == SoundState.Stopped)
                {
                    m_loopingSounds[i].Play();
                }
            }

            if (m_musicListStart)
            {
                bool newSong = true;
                for (int i = 0; i < m_playList.Length; ++i)
                {
                    if (m_playList[i] != null && m_playList[i].State == SoundState.Stopped)
                    { }
                    else if (m_playList[i] != null)
                    { newSong = false; }
                }

                if (newSong == true)
                {
                    musicList(null);
                }
            }

            if (m_playListStart)
            {
                bool newSong = true;
                for (int i = 0; i < m_playList.Length; ++i)
                {
                    if (m_playList[i] != null && m_playList[i].State == SoundState.Stopped)
                    { }
                    else if (m_playList[i] != null)
                    { newSong = false; }
                }

                if (newSong == true)
                {
                    if (m_random == true) playListrnd();
                    if (m_random == false) playList();
                }
            }

            base.Update(p_gameTime);
        }

        public void playList()
        {
            m_playListStart = true;
            int newListSong = m_lastListSong - 1;
            if (newListSong < m_playList.Length - m_listnr)
            {
                newListSong = 31;
            }
            m_playList[newListSong].Play();
            m_lastListSong = newListSong;
        }

        public void playListrnd()
        {
            m_playListStart = true;
            int dice;
            do
            {
                Random rnd = new Random();
                dice = rnd.Next(29, 31);
            }
            while (dice == m_lastListSong || m_lastListSong == 0);
            m_playList[dice].Play();
            m_lastListSong = dice;
        }

        #endregion

        #region Music List

        public void musicList(string p_newSong)
        {
            int o = 0;
            foreach (String boop in m_musicListString)
            {
                if (m_musicList[31 - o].State == SoundState.Playing)
                {
                    if (p_newSong == m_musicListString[31 - m_musicListSpot] || p_newSong == null)
                        return;
                }
                ++o;
            }

            if (p_newSong != null)
            {
                int tempo;
                tempo = 0 - m_musicListSpot;
                tempo = tempo + 31;

                for (int i = 0; i < m_musicList.Length; ++i)
                {
                    if (m_musicList[i] != null)
                        m_musicList[i].Stop();
                }

                if (p_newSong == "stop")
                    return;

                o = 32;
                //                for (int i = 0; i < musicListString.LastIndexOf; ++i)
                foreach (String boop in m_musicListString)
                {
                    o = o - 1;
                    if (boop == p_newSong)
                    {
                        m_musicList[o].Play();
                        m_musicListSpot = o;
                    }
                }
            }
            else if (p_newSong == null)
            {
                m_musicList[m_musicListSpot].Play();
            }
        }

        public void addMusicListSound(string p_soundName)
        {
            MusicListSound(p_soundName, "Audio//Music//" + p_soundName);
        }

        public void MusicListSound(string p_soundName, string p_soundPath)
        {
            if (m_sounds.ContainsKey(p_soundName)) { }
            else m_sounds.Add(p_soundName, Game.Content.Load<SoundEffect>(p_soundPath));

            int listindex = 0;

            SoundEffect sound;

            if (!m_sounds.TryGetValue(p_soundName, out sound))
            {
                throw new ArgumentException(string.Format("Sound '{0}' not found", p_soundName));
            }

            for (int i = 0; i < m_musicList.Length; ++i)
            {
                if (m_musicList[i] == null)
                {
                    listindex = i;
                }
            }

            // soundVolume = float.Parse(config.getValue("Options", "Music"));

            //soundVolume = 0.8f;

            m_musicList[listindex] = sound.CreateInstance();
            //ÄNDRA NEDANSTÅENDE FÖR ATT ÄNDRA MUSIKVOLYM // TA EV IN VARIABLER FÖR ATT KONTROLLERA INDIVIDUELLA STYCKEN HÄR
            m_musicList[listindex].Volume = 0.15f;
            m_musicList[listindex].Pitch = 0.0f;
            m_musicList[listindex].Pan = 0.0f;

            m_musicListString.Add(p_soundName);
        }

        #endregion

        #region Music effects

        public void MusicFade()
        {
        }

        public void MusicTuneUp()
        {
        }

        #endregion

    }
}
